<template>
  <el-upload
    :headers="{
      'Authorization': token
    }"
    ref="uploadFile"
    :data="fileData"
    action="/api/userSystem/Common/Files"
    :list-type="listType"
    :limit="multiple ? limit : 1"
    :on-exceed="handleExceed"
    :on-preview="handlePreview"
    :on-remove="handleRemove"
    :before-remove="beforeRemove"
    :before-upload="beforeAvatarUpload"
    :on-success="handleAvatarSuccess"
    :file-list="files"
    :show-file-list="!closeTip"
    multiple
  >
    <slot>
      <el-button type="primary">
        点击上传
      </el-button>
    </slot>
    <span v-if="!closeTip" slot="tip" class="tip">
      {{ tip }}
    </span>
  </el-upload>
</template>

<script>
import { getTmpCache } from '@u/cache.js';
import { typeOf } from '@u/common.js';

export default {
  name: 'FileUpload',
  data() {
    return {
      token: getTmpCache('token'),
      files: [],
      isPass: true
    };
  },
  props: {
    fileData: {
      type: Object,
      default: () => {}
    },
    fileList: {
      type: [Object, Array],
      default: () => []
    },
    listType: {
      type: String,
      default: 'text',
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    limit: {
      type: Number,
      default: 5,
    },
    fileSize: {
      type: Number,
      default: 10,
    },
    file: {
      type: Object,
      default: () => {
        return {
          type: 'all',
          msg: ''
        };
      },
    },
    closeTip: {
      type: Boolean,
      default: false
    },
    clear: {
      type: Boolean,
      default: false
    },
    tip: {
      type: String,
      default: '支持扩展名：.rar .zip .doc .docx .jpg...',
    }
  },
  watch: {
    clear: {
      handler(newVal) {
        if (newVal) {
          this.$refs.uploadFile.clearFiles();
          this.$emit('update:clear', false);
        }
      },
      deep: true
    },
    fileList: {
      handler(newVal) {
        if (typeOf(newVal) == 'object') {
          this.files = [];
          if (newVal.id) {
            this.files.push(newVal);
          }
        }
        if (typeOf(newVal) == 'array') {
          this.files = this.$deepCopy(newVal);
        }
      },
      deep: true,
      immediate: true,
    }
  },
  methods: {
    handleAvatarSuccess(res, file, fileList) { // 上传接口连接成功回调
      if (res.code == 200) {
        this.$message.success('上传成功');
        this.$emit('success', res.data);
      } else {
        this.$message.error(res.message);
        const i = fileList.findIndex(f => f == file);
        if (i != -1) {
          fileList.splice(i, 1);
        }
      }
    },
    handlePreview(file) { // 点击预览某个文件
      let obj;
      if (!file.response) {
        obj = {
          id: file.id,
          name: file.name,
          url: file.url
        };
      } else {
        obj = file.response.data;
      }
      window.open(obj.url);
      this.$emit('preview', obj);
    },
    handleExceed() { // 超出上传个数
      this.$message.warning(`只能上传${ this.multiple ? this.limit : '一' }个文件！`);
    },
    beforeRemove(file) { // 移除某个文件之前
      if (this.isPass) {
        return this.$confirm(`确定移除 ${ file.name }？`, '取消确认');
      } else {
        this.isPass = true;
      }
    },
    handleRemove(file) { // 移除某个文件回调
      let obj;
      if (!file.response) {
        obj = {
          id: file.id,
          name: file.name,
          url: file.url
        };
      } else {
        obj = file.response.data;
      }
      this.$emit('remove', obj);
    },
    beforeAvatarUpload(file) { // 在上传文件之前
      const names = file.name.split('.'),
        isSize = file.size / 1024 / 1024 < this.fileSize;
      let isType = true;
      if (this.file.type != 'all') {
        isType = false;
        if (names.length && this.file.type.includes(names[names.length - 1])) {
          isType = true;
        }
      }
      this.isPass = isType && isSize;
      if (!isType) {
        this.$message.error(this.file.msg);
        return this.isPass;
      }
      if (!isSize) {
        this.$message.error(`上传文件大小不能超过${ this.fileSize }MB！`);
        return this.isPass;
      }
      return this.isPass;
    }
  }
};
</script>

<style lang="scss" scoped>
.tip {
  margin-left: 5px;
  white-space: nowrap;
}
</style>
